import os
import stat
import tempfile
import shutil
import platform
from typing import Optional


class SecurityManager:
    def __init__(self, sandbox_dir: Optional[str] = None):
        """
        初始化安全管理器
        
        :param sandbox_dir: 沙箱目录路径
        """
        if sandbox_dir is None:
            self.sandbox_dir = tempfile.mkdtemp(prefix="oj_sandbox_")
        else:
            self.sandbox_dir = sandbox_dir
            if not os.path.exists(self.sandbox_dir):
                os.makedirs(self.sandbox_dir)
        
        # 设置沙箱目录权限
        self._set_sandbox_permissions()
    
    def _set_sandbox_permissions(self):
        """
        设置沙箱目录权限，限制访问
        """
        if platform.system() != "Windows":
            # 在非Windows系统上设置权限
            os.chmod(self.sandbox_dir, stat.S_IRWXU)  # 只允许所有者读写执行
    
    def validate_executable(self, executable_path: str) -> bool:
        """
        验证可执行文件是否安全
        
        :param executable_path: 可执行文件路径
        :return: 是否安全
        """
        # 检查文件是否存在
        if not os.path.exists(executable_path):
            return False
        
        # 检查文件大小（防止过大的文件）
        file_size = os.path.getsize(executable_path)
        if file_size > 100 * 1024 * 1024:  # 100MB限制
            return False
        
        return True
    
    def create_sandboxed_copy(self, executable_path: str) -> str:
        """
        在沙箱中创建可执行文件的副本
        
        :param executable_path: 原始可执行文件路径
        :return: 沙箱中的文件路径
        """
        # 获取文件名
        filename = os.path.basename(executable_path)
        sandboxed_path = os.path.join(self.sandbox_dir, filename)
        
        # 复制文件到沙箱
        shutil.copy2(executable_path, sandboxed_path)
        
        # 设置权限
        if platform.system() != "Windows":
            os.chmod(sandboxed_path, stat.S_IRWXU)  # 只允许所有者执行
        
        return sandboxed_path
    
    def cleanup(self):
        """
        清理沙箱目录
        """
        if os.path.exists(self.sandbox_dir):
            shutil.rmtree(self.sandbox_dir)
    
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cleanup()


def is_safe_executable(executable_path: str) -> bool:
    """
    检查可执行文件是否安全
    
    :param executable_path: 可执行文件路径
    :return: 是否安全
    """
    with SecurityManager() as security_manager:
        return security_manager.validate_executable(executable_path)


def run_in_sandbox(executable_path: str) -> str:
    """
    在沙箱中运行可执行文件
    
    :param executable_path: 可执行文件路径
    :return: 沙箱中的文件路径
    """
    with SecurityManager() as security_manager:
        return security_manager.create_sandboxed_copy(executable_path)
